<!DOCTYPE html>
<html>
<head>
<title>readme.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">

<style>
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

body {
	font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
	font-size: 14px;
	padding: 0 12px;
	line-height: 22px;
	word-wrap: break-word;
}

#code-csp-warning {
	position: fixed;
	top: 0;
	right: 0;
	color: white;
	margin: 16px;
	text-align: center;
	font-size: 12px;
	font-family: sans-serif;
	background-color:#444444;
	cursor: pointer;
	padding: 6px;
	box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}

#code-csp-warning:hover {
	text-decoration: none;
	background-color:#007acc;
	box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}


body.scrollBeyondLastLine {
	margin-bottom: calc(100vh - 22px);
}

body.showEditorSelection .code-line {
	position: relative;
}

body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
	content: "";
	display: block;
	position: absolute;
	top: 0;
	left: -12px;
	height: 100%;
}

body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
	left: -30px;
}

.vscode-light.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(0, 0, 0, 0.15);
}

.vscode-light.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(0, 0, 0, 0.40);
}

.vscode-dark.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 255, 255, 0.4);
}

.vscode-dark.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 255, 255, 0.60);
}

.vscode-high-contrast.showEditorSelection .code-active-line:before {
	border-left: 3px solid rgba(255, 160, 0, 0.7);
}

.vscode-high-contrast.showEditorSelection .code-line:hover:before {
	border-left: 3px solid rgba(255, 160, 0, 1);
}

img {
	max-width: 100%;
	max-height: 100%;
}

a {
	color: #4080D0;
	text-decoration: none;
}

a:focus,
input:focus,
select:focus,
textarea:focus {
	outline: 1px solid -webkit-focus-ring-color;
	outline-offset: -1px;
}

hr {
	border: 0;
	height: 2px;
	border-bottom: 2px solid;
}

h1 {
	padding-bottom: 0.3em;
	line-height: 1.2;
	border-bottom-width: 1px;
	border-bottom-style: solid;
}

h1, h2, h3 {
	font-weight: normal;
}

h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
	font-size: inherit;
	line-height: auto;
}

a:hover {
	color: #4080D0;
	text-decoration: underline;
}

table {
	border-collapse: collapse;
}

table > thead > tr > th {
	text-align: left;
	border-bottom: 1px solid;
}

table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
	padding: 5px 10px;
}

table > tbody > tr + tr > td {
	border-top: 1px solid;
}

blockquote {
	margin: 0 7px 0 5px;
	padding: 0 16px 0 10px;
	border-left: 5px solid;
}

code {
	font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
	font-size: 14px;
	line-height: 19px;
}

body.wordWrap pre {
	white-space: pre-wrap;
}

.mac code {
	font-size: 12px;
	line-height: 18px;
}

pre:not(.hljs),
pre.hljs code > div {
	padding: 16px;
	border-radius: 3px;
	overflow: auto;
}

/** Theming */

.vscode-light,
.vscode-light pre code {
	color: rgb(30, 30, 30);
}

.vscode-dark,
.vscode-dark pre code {
	color: #DDD;
}

.vscode-high-contrast,
.vscode-high-contrast pre code {
	color: white;
}

.vscode-light code {
	color: #A31515;
}

.vscode-dark code {
	color: #D7BA7D;
}

.vscode-light pre:not(.hljs),
.vscode-light code > div {
	background-color: rgba(220, 220, 220, 0.4);
}

.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
	background-color: rgba(10, 10, 10, 0.4);
}

.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
	background-color: rgb(0, 0, 0);
}

.vscode-high-contrast h1 {
	border-color: rgb(0, 0, 0);
}

.vscode-light table > thead > tr > th {
	border-color: rgba(0, 0, 0, 0.69);
}

.vscode-dark table > thead > tr > th {
	border-color: rgba(255, 255, 255, 0.69);
}

.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
	border-color: rgba(0, 0, 0, 0.18);
}

.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
	border-color: rgba(255, 255, 255, 0.18);
}

.vscode-light blockquote,
.vscode-dark blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.vscode-high-contrast blockquote {
	background: transparent;
	border-color: #fff;
}
</style>

<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */

/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
	color: #8e908c;
}

/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
	color: #c82829;
}

/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
	color: #f5871f;
}

/* Tomorrow Yellow */
.hljs-attribute {
	color: #eab700;
}

/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
	color: #718c00;
}

/* Tomorrow Blue */
.hljs-title,
.hljs-section {
	color: #4271ae;
}

/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
	color: #8959a8;
}

.hljs {
	display: block;
	overflow-x: auto;
	color: #4d4d4c;
	padding: 0.5em;
}

.hljs-emphasis {
	font-style: italic;
}

.hljs-strong {
	font-weight: bold;
}
</style>

<style>
/*
 * Markdown PDF CSS
 */

 body {
	font-family:  "Meiryo", "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
}

pre {
	background-color: #f8f8f8;
	border: 1px solid #cccccc;
	border-radius: 3px;
	overflow-x: auto;
	white-space: pre-wrap;
	overflow-wrap: break-word;
}

pre:not(.hljs) {
	padding: 23px;
	line-height: 19px;
}

blockquote {
	background: rgba(127, 127, 127, 0.1);
	border-color: rgba(0, 122, 204, 0.5);
}

.emoji {
	height: 1.4em;
}

/* for inline code */
:not(pre):not(.hljs) > code {
	color: #C9AE75; /* Change the old color so it seems less like an error */
	font-size: inherit;
}

/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
	page-break-after: always;
}

</style>

</head>
<body>
<h1 id="%E9%9C%80%E6%B1%82">需求</h1>
<h2 id="%E6%80%BB%E9%9C%80%E6%B1%82-%E6%A1%8C%E9%9D%A2%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E8%83%BD%E7%9B%91%E5%90%AC%E6%B5%8F%E8%A7%88%E5%99%A8%E7%AA%97%E5%8F%A3%E5%8F%98%E5%8C%96%E5%8F%8A%E7%9B%B8%E5%85%B3%E9%80%9A%E7%9F%A5">总需求 =&gt; 桌面应用程序能监听浏览器窗口变化及相关通知</h2>
<h2 id="%E7%BB%86%E5%88%86%E9%9C%80%E6%B1%82">细分需求</h2>
<h3 id="1%E6%B5%8F%E8%A7%88%E5%99%A8%E5%B7%A6%E4%B8%8A%E8%A7%92%E7%9B%B8%E5%AF%B9%E5%B1%8F%E5%B9%95%E4%BD%8D%E7%BD%AE">1.浏览器左上角相对屏幕位置</h3>
<h3 id="2%E6%B5%8F%E8%A7%88%E5%99%A8%E5%A4%96%E6%A1%86%E5%A4%A7%E5%B0%8F">2.浏览器外框大小</h3>
<h3 id="3%E6%B5%8F%E8%A7%88%E5%99%A8%E5%8F%AF%E8%A7%81%E5%8C%BA%E5%9F%9F">3.浏览器可见区域</h3>
<h3 id="4%E6%B5%8F%E8%A7%88%E5%99%A8%E5%A4%A7%E5%B0%8F%E6%9C%80%E5%8C%96%E6%9C%80%E5%B0%8F%E5%8C%96%E6%9C%80%E5%A4%A7%E5%8C%96%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC">4.浏览器大小最化,最小化,最大化事件监听</h3>
<h3 id="5%E5%85%83%E7%B4%A0%E7%9B%B8%E5%AF%B9%E5%B1%8F%E5%B9%95%E7%BB%9D%E5%AF%B9%E5%AE%9A%E4%BD%8D">5.元素相对屏幕绝对定位</h3>
<h3 id="6%E6%B5%8F%E8%A7%88%E5%99%A8%E6%8B%96%E6%8B%BD%E4%BA%8B%E4%BB%B6">6.浏览器拖拽事件</h3>
<h3 id="7%E8%A2%ABexe%E6%9C%AC%E5%9C%B0%E7%A8%8B%E5%BA%8F%E7%BD%AE%E9%A1%B6%E9%81%AE%E6%A1%A3%E7%9A%84div%E6%98%AF%E5%90%A6%E8%83%BD%E8%A7%A6%E5%8F%91drop%E4%BA%8B%E4%BB%B6">7.被exe本地程序置顶遮档的div,是否能触发drop事件</h3>
<h3 id="8websocket%E5%85%BC%E5%AE%B9%E6%80%A7%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8%E8%B7%A8%E5%9F%9F">8.websocket兼容性,是否存在跨域</h3>
<h3 id="9web%E4%B8%8E%E5%8E%9F%E7%94%9F%E4%BA%A4%E4%BA%92%E6%96%B9%E6%A1%88-%E6%89%A9%E5%B1%95">9.web与原生交互方案-扩展</h3>
<h2 id="%E6%9C%80%E7%BB%88%E5%8F%96%E7%82%B9%E4%BD%8D%E7%BD%AE">最终取点位置</h2>
<p><img src="https://gitee.com/xueyejinghong/WebDemo/raw/master/00/imgs/final_position.png" alt=""></p>
<center>图一</center>
<h1 id="%E5%B1%8F%E5%B9%95%E4%BF%A1%E6%81%AF">屏幕信息</h1>
<p><img src="https://images2015.cnblogs.com/blog/153475/201512/153475-20151231161329104-781827200.png" alt=""></p>
<center>图二</center>
<blockquote>
<p>screen.height ：屏幕高度。</p>
</blockquote>
<blockquote>
<p>screen.width ：屏幕宽度。</p>
</blockquote>
<blockquote>
<p>screen.availHeight ：屏幕可用高度。即屏幕高度减去上下任务栏后的高度，可表示为软件最大化时的高度。</p>
</blockquote>
<blockquote>
<p>screen.availWidth ：屏幕可用宽度。即屏幕宽度减去左右任务栏后的宽度，可表示为软件最大化时的宽度。</p>
</blockquote>
<blockquote>
<p>任务栏高/宽度 ：可通过屏幕高/宽度 减去 屏幕可用高/宽度得出。如：任务栏高度 = screen.height - screen.availHeight 。</p>
</blockquote>
<blockquote>
<p>特别说明:如任务栏不在底部,则screen.height==screen.availHeight</p>
</blockquote>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> data={
  <span class="hljs-attr">screenHeight</span>: <span class="hljs-built_in">window</span>.screen.height,
  <span class="hljs-attr">screenWidth</span>: <span class="hljs-built_in">window</span>.screen.width,
  <span class="hljs-attr">screenAvailWidth</span>: <span class="hljs-built_in">window</span>.screen.availWidth,
  <span class="hljs-attr">screenAvailHeight</span>: <span class="hljs-built_in">window</span>.screen.availHeight
}
</div></code></pre>
<h1 id="%E6%B5%8F%E8%A7%88%E5%99%A8%E7%AA%97%E5%8F%A3%E4%BD%8D%E7%BD%AE">浏览器窗口位置</h1>
<p><img src="https://images2015.cnblogs.com/blog/153475/201512/153475-20151222173139109-87271821.png" alt=""></p>
<center>图三</center>
<h2 id="%E4%B8%80%EF%BC%8E%E7%AA%97%E5%8F%A3%E4%BD%8D%E7%BD%AE%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81">一．窗口位置测试代码</h2>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> obj = {
  <span class="hljs-attr">screenLeft</span>: <span class="hljs-built_in">window</span>.screenLeft,
  <span class="hljs-attr">screenTop</span>: <span class="hljs-built_in">window</span>.screenTop,

  <span class="hljs-attr">appinnerWidth</span>: <span class="hljs-built_in">window</span>.innerWidth,
  <span class="hljs-attr">appinnerHeight</span>: <span class="hljs-built_in">window</span>.innerHeight
};
</div></code></pre>
<h2 id="%E4%BA%8C%E6%89%93%E5%8D%B0%E7%BB%93%E6%9E%9C%E7%9B%B8%E5%90%8C%E4%BD%8D%E7%BD%AE%E6%B5%8F%E8%A7%88%E5%99%A8%E5%A4%96%E8%BD%AE%E9%83%AD%E5%B7%A6%E4%B8%8A%E9%A1%B6%E7%82%B9%E5%90%8C%E5%AE%BD%E5%90%8C%E9%AB%98">二.打印结果相同位置(浏览器外轮郭左上顶点,同宽同高)</h2>
<table>
<thead>
<tr>
<th></th>
<th style="text-align:center">chrome</th>
<th style="text-align:right">IE</th>
<th style="text-align:right">相差</th>
</tr>
</thead>
<tbody>
<tr>
<td>screenTop</td>
<td style="text-align:center">94</td>
<td style="text-align:right">171</td>
<td style="text-align:right">78</td>
</tr>
<tr>
<td>screenLeft</td>
<td style="text-align:center">133</td>
<td style="text-align:right">141</td>
<td style="text-align:right">8</td>
</tr>
<tr>
<td>innerWidth</td>
<td style="text-align:center">685</td>
<td style="text-align:right">685</td>
<td style="text-align:right">0</td>
</tr>
<tr>
<td>innerWidth</td>
<td style="text-align:center">720</td>
<td style="text-align:right">754</td>
<td style="text-align:right">34</td>
</tr>
</tbody>
</table>
<h2 id="%E4%B8%89-%E7%BB%93%E6%9E%9C%E5%88%86%E6%9E%90">三. 结果分析</h2>
<ol>
<li>
<p>screenTop偏差, screenTop相对点不一样.IE7+都支持,但IE的screenTop 相对于document窗口左顶点,如下图</p>
<p><img src="https://gitee.com/xueyejinghong/WebDemo/raw/master/00/imgs/win_position_start.png" alt=""></p>
</li>
</ol>
<center>图四</center>
<ol start="2">
<li>screenLeft,非最大化时相差8px,最大化无偏差</li>
</ol>
<h2 id="%E5%9B%9B-%E7%82%B91%E5%8F%96%E6%B3%95">四. 点1取法</h2>
<ol>
<li>
<p>chrome下点1位置直接可知</p>
</li>
<li>
<p>IE下点位2能正常得到,那么如何得到点一坐标,看下面公式
outerHeight-innderHeight=(top点2-top点1)+横向滚动条(如有)</p>
</li>
</ol>
<h2 id="%E4%BA%94-%E7%82%B92%E5%8F%96%E6%B3%95">五. 点2取法</h2>
<ol>
<li>
<p>IE下直screenTop就直接相对点2</p>
</li>
<li>
<p>chrome下 screenTop+(outerHeight-innerHeight)</p>
</li>
</ol>
<h2 id="%E4%BA%94-%E6%9C%80%E7%BB%88%E4%BB%A3%E7%A0%81">五. 最终代码</h2>
<pre class="hljs"><code><div>{
  <span class="hljs-attr">ca</span>: <span class="hljs-built_in">window</span>.outerHeight - <span class="hljs-built_in">window</span>.innerHeight,

  <span class="hljs-comment">//非全屏时修正8px</span>
  chromeToolHeight: <span class="hljs-built_in">window</span>.outerHeight - <span class="hljs-built_in">window</span>.innerHeight - <span class="hljs-number">8</span>,
  <span class="hljs-attr">ieToolHeight</span>:
    <span class="hljs-built_in">window</span>.screenTop - (<span class="hljs-built_in">window</span>.outerHeight - <span class="hljs-built_in">window</span>.innerHeight - <span class="hljs-number">30</span>),

  <span class="hljs-comment">//screenTop是窗口顶点</span>
  chromeDocY:
    <span class="hljs-built_in">window</span>.screenTop + (<span class="hljs-built_in">window</span>.outerHeight - <span class="hljs-built_in">window</span>.innerHeight - <span class="hljs-number">8</span>),
  <span class="hljs-comment">//ie就直接取了screenTop就是文档左上</span>
  IEDocY: <span class="hljs-built_in">window</span>.screenTop
}
</div></code></pre>
<h1 id="%E6%B5%8F%E8%A7%88%E5%99%A8%E6%98%BE%E7%A4%BA%E4%B8%8E%E9%9A%90%E8%97%8F">浏览器显示与隐藏</h1>
<h2 id="%E4%B8%80%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81">一.测试代码</h2>
<pre class="hljs"><code><div><span class="hljs-keyword">if</span> (<span class="hljs-built_in">document</span>.addEventListener) {
  <span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">"visibilitychange"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">document</span>.visibilityState);
  });
}
</div></code></pre>
<h2 id="%E4%BA%8C%E7%BB%93%E6%9E%9C">二.结果</h2>
<ol>
<li>
<p>Chrome | FF | IE11 | IE10 皆可监听到</p>
</li>
<li>
<p>IE9 及以下不支持</p>
</li>
<li>
<p>同时 tab 切换也能监听得到</p>
</li>
</ol>
<h1 id="%E9%A1%B5%E9%9D%A2%E5%85%B3%E9%97%AD%E5%8F%8A%E5%88%B7%E6%96%B0-windowonbeforeunload">页面关闭及刷新 window.onbeforeunload</h1>
<h2 id="%E4%B8%80-%E6%B5%8B%E8%AF%95%E4%BB%A3%E7%A0%81">一. 测试代码</h2>
<pre class="hljs"><code><div><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onclose</span>(<span class="hljs-params"></span>) </span>{
  localStorage.setItem(<span class="hljs-string">"onclose"</span>, <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().getTime());
}
<span class="hljs-built_in">window</span>.onbeforeunload = onclose;
</div></code></pre>
<h2 id="%E4%BA%8C-%E7%BB%93%E6%9E%9C">二. 结果</h2>
<ol>
<li>Chrome | FF | IE11 | IE10 | IE9 | IE8 皆可</li>
</ol>
<h1 id="%E6%B5%8F%E8%A7%88%E5%99%A8%E7%AA%97%E5%8F%A3%E6%8B%96%E6%8B%BD">浏览器窗口拖拽</h1>
<blockquote>
<ol>
<li>不支持,超出 HTML 的范畴,属应用层面问题</li>
</ol>
</blockquote>
<h1 id="%E6%B5%8F%E8%A7%88%E5%99%A8%E7%AA%97%E5%8F%A3%E5%A4%A7%E5%B0%8F%E5%8F%98%E5%8C%96">浏览器窗口大小变化</h1>
<ol>
<li>最小化/最大化 visibilitychange 可监听得到</li>
</ol>
<pre class="hljs"><code><div>$(<span class="hljs-built_in">window</span>).resize(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">//当浏览器大小变化时</span>
  <span class="hljs-built_in">console</span>.log($(<span class="hljs-built_in">window</span>).width()); <span class="hljs-comment">//浏览器高度</span>
  <span class="hljs-built_in">console</span>.log($(<span class="hljs-built_in">window</span>).height()); <span class="hljs-comment">//浏览器宽度</span>
});
</div></code></pre>
<h1 id="websocket-%E6%94%AF%E6%8C%81%E6%83%85%E5%86%B5">webSocket 支持情况</h1>
<h3 id="%E4%B8%80-%E4%BB%A3%E7%A0%81">一. 代码</h3>
<pre class="hljs"><code><div><span class="hljs-keyword">var</span> ws = <span class="hljs-built_in">require</span>(<span class="hljs-string">"nodejs-websocket"</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"开始建立连接..."</span>);
<span class="hljs-keyword">var</span> game1 = <span class="hljs-literal">null</span>,
  game2 = <span class="hljs-literal">null</span>,
  game1Ready = <span class="hljs-literal">false</span>,
  game2Ready = <span class="hljs-literal">false</span>;
<span class="hljs-keyword">var</span> server = ws
  .createServer(<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">conn</span>) </span>{
    conn.on(<span class="hljs-string">"text"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">str</span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"收到的信息为:"</span> + str);
      <span class="hljs-keyword">if</span> (str === <span class="hljs-string">"game1"</span>) {
        game1 = conn;
        game1Ready = <span class="hljs-literal">true</span>;
        conn.sendText(<span class="hljs-string">"success"</span>);
      }
      <span class="hljs-keyword">if</span> (str === <span class="hljs-string">"game2"</span>) {
        game2 = conn;
        game2Ready = <span class="hljs-literal">true</span>;
      }

      <span class="hljs-keyword">if</span> (game1Ready &amp;&amp; game2Ready) {
        game2.sendText(str);
      }

      conn.sendText(str);
    });
    conn.on(<span class="hljs-string">"close"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">code, reason</span>) </span>{
      <span class="hljs-built_in">console</span>.log(reason, <span class="hljs-string">"reason"</span>);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"关闭连接"</span>);
    });
    conn.on(<span class="hljs-string">"error"</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">code, reason</span>) </span>{
      <span class="hljs-built_in">console</span>.log(reason, <span class="hljs-string">"reason"</span>);
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"异常关闭"</span>);
    });
  })
  .listen(<span class="hljs-number">843</span>,<span class="hljs-string">'10.255.252.126'</span>);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"WebSocket建立完毕"</span>);

</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-meta">&lt;!DOCTYPE html&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Document<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-class">.kuang</span> {
        <span class="hljs-attribute">text-align</span>: left;
      }
      <span class="hljs-selector-id">#mess</span> {
        <span class="hljs-attribute">text-align</span>: left;
      }
      <span class="hljs-selector-class">.value</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100px</span>;
        <span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid;
        <span class="hljs-attribute">text-align</span>: left;
        <span class="hljs-attribute">line-height</span>: <span class="hljs-number">50px</span>;
        <span class="hljs-attribute">display</span>: inline-block;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"mess"</span>&gt;</span>正在连接...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"kuang"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"value"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"value1"</span>&gt;</span>小明<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"value"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"value2"</span>&gt;</span>小王<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"value"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"value3"</span>&gt;</span>小张<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">var</span> mess = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"mess"</span>);
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.WebSocket) {
        <span class="hljs-keyword">var</span> ws = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">"ws://10.255.252.126:843"</span>);

        ws.onopen = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"连接服务器成功"</span>);
          ws.send(<span class="hljs-string">"game1"</span>);
        };
        ws.onclose = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"服务器关闭"</span>);
        };
        ws.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"连接出错"</span>);
        };

        ws.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          mess.innerHTML = <span class="hljs-string">"连接成功"</span>;
          <span class="hljs-built_in">document</span>.querySelector(<span class="hljs-string">".kuang"</span>).onclick = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
            <span class="hljs-keyword">var</span> time = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
            ws.send(time + <span class="hljs-string">"  game1点击了“"</span> + e.target.innerHTML + <span class="hljs-string">"”"</span>);
          };
        };
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>

</div></code></pre>
<pre class="hljs"><code><div><span class="hljs-meta">&lt;!DOCTYPE html&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Document<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-class">.kuang</span> {
        <span class="hljs-attribute">text-align</span>: center;
        <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">200px</span>;
      }
      <span class="hljs-selector-id">#mess</span> {
        <span class="hljs-attribute">text-align</span>: center;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"mess"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">var</span> mess = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"mess"</span>);
      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.WebSocket) {
        <span class="hljs-keyword">var</span> ws = <span class="hljs-keyword">new</span> WebSocket(<span class="hljs-string">"ws://10.255.252.126:843"</span>);

        ws.onopen = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"连接服务器成功"</span>);
          ws.send(<span class="hljs-string">"game2"</span>);
        };
        ws.onclose = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"服务器关闭"</span>);
        };
        ws.onerror = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"连接出错"</span>);
        };

        ws.onmessage = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
          <span class="hljs-keyword">var</span> time = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
          mess.innerHTML += time + <span class="hljs-string">"的消息："</span> + e.data + <span class="hljs-string">"&lt;br&gt;"</span>;
        };
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>

</div></code></pre>
<h3 id="%E4%BA%8C%E6%89%93%E5%BC%80%E5%90%8E%E7%BB%93%E6%9E%9C">二.打开后结果</h3>
<p><img src="https://gitee.com/xueyejinghong/WebDemo/raw/master/00/imgs/socket_success.png" alt=""></p>
<center>Chrome</center>
<p><img src="https://gitee.com/xueyejinghong/WebDemo/raw/master/00/imgs/socket_success_ie.png" alt=""></p>
<center>IE</center>
<ol>
<li>
<p>IE9+(不含),Chrome,FF 皆支持</p>
</li>
<li>
<p>替代方案 socket.io 亲测试可以模拟出</p>
</li>
</ol>
<h1 id="%E7%A4%BA%E4%BE%8B-git">示例 git</h1>
<p>https://gitee.com/xueyejinghong/WebDemo/tree/master/00
https://gitee.com/xueyejinghong/WebDemo/tree/master/01_Node</p>
<h1 id="%E5%8F%82%E8%80%83%E6%96%87%E6%A1%A3">参考文档</h1>
<p>https://www.cnblogs.com/fsyz/p/7854072.html</p>
<p>https://www.cnblogs.com/moqiutao/p/5050225.html</p>
<p>https://www.cnblogs.com/yc-code/p/4553934.html</p>

</body>
</html>
